import hashlib
import hmac
import json
import requests
import time
import sys
import base64

from coin.exchange.base.kr_rest.auth_base import AuthKey
from coin2.api_client.common import (SyncQueryer)

class GdaxAuth(requests.auth.AuthBase):
  def __init__(self, key):
    self._key = AuthKey.from_file(key)
    self._key.passphrase = self._key.get_value('passphrase')

  def gen_auth(self, timestamp, method, path_url, body=None):
    """Auth method reused for both rest and ws"""
    if body is not None:
      body = body.decode()
    else:
      body = ''
    message = timestamp + method + path_url + body
    hmac_key = base64.b64decode(self._key.secret_key)
    signature = hmac.new(hmac_key, message.encode(), hashlib.sha256)
    signature_b64 = base64.b64encode(signature.digest()).decode()
    return {
        'CB-ACCESS-SIGN': signature_b64,
        'CB-ACCESS-TIMESTAMP': timestamp,
        'CB-ACCESS-KEY': self._key.api_key,
        'CB-ACCESS-PASSPHRASE': self._key.passphrase,
        'Content-Type': 'application/json'
    }

  def __call__(self, req: requests.PreparedRequest):
    ts = int(time.time_ns() / 1000000)
    ts_str = str(ts)
    str0, str1 = ts_str[:-3], ts_str[len(ts_str) - 3: len(ts_str)]
    ts_str = str0 + "." + str1
    sign_header = self.gen_auth(ts_str, req.method, req.path_url, req.body)
    req.headers.update(sign_header)
    return req


class GdaxPrivateClient():
  def __init__(self, key, mea):
    self._key = key
    self._auth = GdaxAuth(key)
    if mea == "Spot.Gdax.v1":
      self._url = "https://api.pro.coinbase.com"
    else:
      assert (0)
    self._query = SyncQueryer(api_host=self._url, auth=self._auth)

  def get_open_order(self):
    method = "GET"
    path = '/orders'
    params = {}
    response = self._query.query(
        method=method, path=path, params=params)
    return response

  def transfers(self, account: str):
    method = "GET"
    path = "accounts/{}/ledger".format(account)
    params = {"limit": 1000}
    response = self._query.query(method=method, path=path, params=params)
    response = response.json()
    return response

  def query_account_balance(self):
    method = "GET"
    path = "/accounts"
    response = self._query.query(method=method, path=path)
    response = response.json()
    return response

  def query_deposit_or_withdrawal(self):
    method = "GET"
    path = "/transfers"
    response = self._query.query(method=method, path=path)
    response = response.json()
    return response

if __name__ == "__main__":
  key_path = sys.argv[1]
  config = {"key_path": key_path, "mea": "Spot.Gdax.v1"}
  gdax = GdaxPrivateClient(key_path, "Spot.Gdax.v1")
  resp = gdax.query_account_balance()
  resp = gdax.account()
  resp = gdax.transfers("4843bc29-f19e-42b3-b875-d198d0c78165")
  print(json.dumps(resp, indent=2))
